home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 52
/
Amiga Format AFCD52 (Issue 136, May 2000).iso
/
-in_the_mag-
/
multitasking
/
monitors
/
tasky
/
source
/
tasklist.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-03-05
|
5KB
|
256 lines
/*
* Routines to copy task list to another list.
* For TaskY and xDataPrefs.
* Many specific changes for TaskY.
*
* Martin W. Scott, 23 March 1993.
*/
#include <exec/types.h>
#include <exec/tasks.h>
#include <exec/memory.h>
#include <exec/execbase.h>
#include <dos/dos.h>
#include <dos/dosextens.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <string.h>
#include "sprintf.h"
extern struct ExecBase *SysBase;
#include "ptask.h"
static LIST tmplist;
LIST ptlist;
LONG num_ptasks;
void
InitPTaskList()
{
NewList(&ptlist);
}
/* clear list, freeing memory */
void
DeletePTaskList()
{
PTASK *pt;
Forbid();
while (pt = (PTASK *)RemHead(&ptlist))
{
FreeVec(pt->pt_Node.ln_Name);
FreeVec(pt->pt_OrigName);
FreeVec(pt);
}
Permit();
}
/* allocate memory region of size len+1, copy string to it */
/* tasky specific: pad string out with spaces and priority at end */
#define WIDTH 27 /* name width */
#define FULLWIDTH (WIDTH+4) /* total width -- 4 chars for priority */
char *
AllocStr(UBYTE len, BYTE pri, UBYTE *str)
{
char *newstr;
UWORD i;
BOOL trunc = FALSE;
if (len > WIDTH) /* truncate length? */
len = WIDTH, trunc = TRUE;
if (newstr = AllocVec(FULLWIDTH+1,0L))
{
CopyMem(str,newstr,len);
for (i = len; i < WIDTH; i++)
newstr[i]=' ';
if (trunc)
newstr[WIDTH-1] = '$';
SPrintf(&newstr[WIDTH], "%4ld", (long)pri);
}
return newstr;
}
#define FreeStr(s) FreeVec(s)
/* insert node in sorted position in list (sort by name) */
void
InsertInPlace(LIST *list, NODE *new)
{
NODE *n;
for (n = list->lh_Head; n->ln_Succ; n = n->ln_Succ)
{
if (stricmp(n->ln_Name, new->ln_Name) >= 0)
{
Insert(list,new,n->ln_Pred);
return;
}
}
/* got here - must be last node */
AddTail(list, new);
}
/* create a sorted list from a list */
void
SortList(LIST *from, LIST *to)
{
NODE *n;
while (n = RemHead(from))
InsertInPlace(to, n);
}
/* set up pnode from given task-node */
BOOL
InitNode(PTASK *pt, NODE *n, char *name, UBYTE len)
{
UWORD i;
if (pt->pt_OrigName = AllocVec(i=(strlen(n->ln_Name)+1), 0L))
{
CopyMem(n->ln_Name, pt->pt_OrigName, i);
if (pt->pt_Node.ln_Name = AllocStr(len, n->ln_Pri, name))
{
AddHead(&tmplist, pt);
pt->pt_Task = (TASK *)n;
pt->pt_TaskPri = n->ln_Pri;
return TRUE;
}
FreeVec(pt->pt_OrigName);
}
return FALSE;
}
/* add a new task to our list */
BOOL
AddTaskToPTaskList(TASK *t)
{
UBYTE cmdname[300];
PTASK *pt;
num_ptasks++; /* increment count */
if (pt = AllocPTask()) /* get a new PTask */
{
PROC *proc = (PROC *)t; /* proc from task */
/* task or non-cli process */
if (t->tc_Node.ln_Type != NT_PROCESS || proc->pr_TaskNum == 0)
{
char *name = t->tc_Node.ln_Name;
if (InitNode(pt, t, name, strlen(name)))
return TRUE;
}
else /* cli-process...fun and games */
{
struct CommandLineInterface *cli = BADDR(proc->pr_CLI);
UBYTE *bstr = BADDR(cli->cli_CommandName);
UBYTE len;
if (bstr && bstr[0]) { /* a command is loaded */
len = bstr[0];
bstr = &bstr[1];
} else {
bstr = "No command loaded";
len = 17;
}
CopyMem(bstr, cmdname, len);
SPrintf(&cmdname[len]," [CLI %ld]", proc->pr_TaskNum);
if (InitNode(pt, t, cmdname, len+strlen(&cmdname[len])))
return TRUE;
}
FreePTask(pt); /* memory allocation failure... */
}
return FALSE;
}
/* add tasks from supplied task list to our list */
/* return TRUE if okay, FALSE if memory allocation failed */
BOOL
AddListToPTaskList(LIST *tl)
{
TASK *t;
/* scan the list, adding processes to the plist */
for (t = (TASK *)tl->lh_Head; t->tc_Node.ln_Succ; t = (TASK *)t->tc_Node.ln_Succ)
{
if (!AddTaskToPTaskList(t))
{
Permit();
return FALSE;
}
} /* for */
return TRUE;
}
/* re-read PTask list, deleting old one if required */
/* return success */
BOOL
RefreshPTaskList()
{
static BOOL firsttime = TRUE;
BOOL rc = FALSE;
if (firsttime)
{
InitPTaskList();
NewList(&tmplist);
firsttime = FALSE;
}
else
DeletePTaskList();
num_ptasks = 0; /* reset count */
/* want to be disabled for as short a period as possible, so
build a tmp list, then copy to another in order */
Disable();
if (AddListToPTaskList(&SysBase->TaskReady) &&
AddListToPTaskList(&SysBase->TaskWait) &&
AddTaskToPTaskList(SysBase->ThisTask))
rc = TRUE;
Enable();
SortList(&tmplist, &ptlist);
if (!rc)
DeletePTaskList();
return rc;
}
/* check list for given task - assumes forbidden */
TASK *
ScanList(LIST *list, PTASK *pt)
{
TASK *t;
for (t = (TASK *)FindName(list, pt->pt_OrigName);
t && t != pt->pt_Task;
t = (TASK *)FindName((LIST *)t, pt->pt_OrigName))
;
return t;
}
/* check task lists for given task */
TASK *
GetOrigTask(PTASK *pt)
{
TASK *t;
Disable();
t = ScanList(&SysBase->TaskReady, pt);
if (!t)
t = ScanList(&SysBase->TaskWait, pt);
Enable();
if (!t) /* is it us? */
if (pt->pt_Task == SysBase->ThisTask)
t = SysBase->ThisTask;
return t;
}